home *** CD-ROM | disk | FTP | other *** search
- /* ctest.c - a couple of benchmarks for c */
-
- /* The first is a procedure call benchmark that computes fibonacci
- numbers. */
-
- /* The second is a floating point benchmark derived from: */
-
- /* SIERP.C -- (C) 1990 by Dick Oliver, R1 Box 5140, Morrisville, VT 05661
- A program to "draw" and "paint" Sierpinksi's Triangle, defined by a
- "seed" (or "parent") shape and three transformations of that shape
- ("children"). You may copy, modify, and recompile this source code
- as you please, as long as you do not sell it or any product produced
- from any part of it. The author makes no claims as to readability or
- suitability for a particular task, but I'll be happy to give advice
- and assistance. */
-
- #include <stdio.h> /* For getch() */
- #include <math.h> /* For cos() and sin() */
- #include <time.h>
-
- #define CLOOPCNT 100 /* default number of call iterations */
- #define TLOOPCNT 100 /* default number of tree iterations */
-
- void init_graphics(void);
- void done_graphics(void);
- void clear_screen(void);
- void moveto(int x, int y);
- void lineto(int x, int y);
- long atol(char *str);
-
- #define NPOINTS 4 /* Number of points on the "parent" polygon */
- #define NTRANS 6 /* Number of transformed "children" */
- #define NLEVELS 5 /* Number of levels to draw */
- #define COUNT 10000 /* Number of dots to paint */
- #define CENTERX 320 /* Center of the screen */
- #define CENTERY 350
- #define SEEDX 6,20,-6,-12 /* The "parent" polygon */
- #define SEEDY -120,120,120,-120
-
- /* The tranformations which define the "children" */
-
- #define MOVEX -41.2,36.9,5.13,-14.64,2.2,40.07 /* Displacement */
- #define MOVEY 14.987,-61.31,7.10,-32.33,-50.46
- #define SIZEX 0.39,0.41,0.52,0.35,0.86,0.37 /* Size change */
- #define SIZEY 0.39,0.31,0.17,0.24,0.79,0.42
- #define SPINX 5.62,0.61,6.15,5.43,3.27,0.54 /* Rotation */
- #define SPINY 4.91,1.27,0.13,4.71,6.28,1.4
-
- int seedx[NPOINTS] = {SEEDX}, /* The "parent" polygon */
- seedy[NPOINTS] = {SEEDY};
-
- /* The tranformations which define the "children" */
- float movex[NTRANS] = {MOVEX}, /* Displacement */
- movey[NTRANS] = {MOVEY},
- sizex[NTRANS] = {SIZEX}, /* Size change */
- sizey[NTRANS] = {SIZEY},
- spinx[NTRANS] = {SPINX}, /* Rotation */
- spiny[NTRANS] = {SPINY},
-
- /* The transformation matrix T, computed from the above variables */
- Ta[NTRANS], Tb[NTRANS], Tc[NTRANS], Td[NTRANS];
-
- /* Function prototypes */
- double call_test(long loopcnt);
- int fib(int n);
- double tree_test(long loopcnt);
- void draw_tree(void);
- void draw(float a, float b, float c, float d, float mx, float my, int iter);
-
- void main(int argc, char **argv)
- {
- double elapsed;
- long loopcnt;
- FILE *fp;
- int i;
-
- /* append to the results file */
- if ((fp = fopen("ctest.out","a")) == NULL)
- exit(1);
-
- /* show the command line */
- for (i = 0; i < argc; ++i)
- fprintf(fp,"%s ",argv[i]);
- putc('\n',fp);
-
- /* do the call test */
- loopcnt = (argc > 1 ? atol(argv[1]) : CLOOPCNT);
- elapsed = call_test(loopcnt);
- fprintf(fp,"%g fib(25)'s/second\n",(double)loopcnt / elapsed);
-
- /* do the tree test */
- loopcnt = (argc > 2 ? atol(argv[2]) : TLOOPCNT);
- elapsed = tree_test(loopcnt);
- fprintf(fp,"%g trees/second\n",(double)loopcnt / elapsed);
- }
-
- double call_test(long loopcnt)
- {
- time_t start,end;
- start = time((time_t)0);
- while (--loopcnt >= 0L)
- (void)fib(25);
- end = time((time_t)0);
- return difftime(end,start);
- }
-
- int fib(int n)
- {
- return n < 2 ? n : fib(n - 1) + fib(n - 2);
- }
-
- double tree_test(long loopcnt)
- {
- time_t start,end;
-
- init_graphics(); /* Initialize the screen */
-
- start = time((time_t)0);
- while (--loopcnt >= 0L) {
- clear_screen();
- draw_tree();
- }
- end = time((time_t)0);
-
- done_graphics(); /* Go back to text mode and exit */
-
- return difftime(end,start);
- }
-
- void draw_tree(void)
- { int t;
-
- /* Compute a,b,c,d from the move, size, and spin variables */
- for (t = 0; t < NTRANS; t++)
- { Ta[t] = sizex[t] * cos(spinx[t]);
- Tb[t] = - sizey[t] * sin(spiny[t]);
- Tc[t] = sizex[t] * sin(spinx[t]);
- Td[t] = sizey[t] * cos(spiny[t]);
- }
-
- /* Invoke draw with an initial transformation to move the triangle
- to the center of the screen, unchanged in size or rotation */
- draw(1.0, 0.0, 0.0, 1.0, (float) CENTERX, (float) CENTERY, NLEVELS);
- }
-
-
- /* This recursive routine draws one "parent" polygon, then calls itself
- to draw the "children" using the transformations defined above */
-
- void draw(float a, float b, float c, float d, float mx, float my, int iter)
- { int t;
- iter--; /* Count one more level of drawing depth */
- { /* Use a,b,c,d,mx,my to transform the polygon */
- float x1, y1; /* Point on the parent */
- int p, x2[NTRANS], y2[NTRANS]; /* Points on the child */
- for (p = 0; p < NPOINTS; p++)
- { x1 = seedx[p];
- y1 = seedy[p];
- x2[p] = a * x1 + b * y1 + mx;
- y2[p] = c * x1 + d * y1 + my;
- }
- /* Now draw the new polygon on the screen */
- moveto(x2[NPOINTS - 1], y2[NPOINTS - 1]);
- for (p = 0; p < NPOINTS; p++) lineto(x2[p], y2[p]);
- }
- if (iter < 0) return; /* If we're at the deepest level, back out */
-
- /* Do a recursive call for each "child" of the polygon we just drew */
- for (t = 0; t < NTRANS; t++)
- { draw(Ta[t] * a + Tc[t] * b,
- Tb[t] * a + Td[t] * b,
- Ta[t] * c + Tc[t] * d,
- Tb[t] * c + Td[t] * d,
- movex[t] * a + movey[t] * b + mx,
- movex[t] * c + movey[t] * d + my,
- iter);
- }
- }